package com.zxshhy.service.impl;

import com.zxshhy.entity.Storage;
import com.zxshhy.mapper.StorageTCCMapper;
import com.zxshhy.service.StorageTCCService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;

@Slf4j
@Service
public class StorageTCCServiceImpl implements StorageTCCService {
    @Resource
    private StorageTCCMapper storageTCCMapper;

    @Transactional
    @Override
    public boolean prepareDeduct(String commodityCode, int count){
        log.info("=============冻结库存=================");
        log.info("当前 XID: {}", RootContext.getXID());
        // 检查库存
        checkStock(commodityCode,count);
        log.info("开始冻结 {} 库存", commodityCode);
        //冻结库存
        Integer record = storageTCCMapper.freezeStorage(commodityCode,count);
        log.info("冻结 {} 库存结果:{}", commodityCode, record > 0 ? "操作成功" : "扣减库存失败");
        if(record == 0) throw new RuntimeException("TCC-->冻结库存try阶段异常");
        return record > 0;
    }

    @Override
    public boolean commit(BusinessActionContext actionContext) {
        log.info("=============提交成功，扣减冻结库存=================");
        String commodityCode = actionContext.getActionContext("commodityCode").toString();
        int count = (int) actionContext.getActionContext("count");
        //扣减冻结库存
        int insertCount = storageTCCMapper.reduceFreezeStorage(commodityCode, count);
        if(insertCount == 0) throw new RuntimeException("TCC-->扣减冻结库存commit异常");
        return insertCount > 0;
    }

    @Override
    public boolean rollback(BusinessActionContext actionContext) {
        log.info("=============异常回滚，解冻库存=================");
        String commodityCode = actionContext.getActionContext("commodityCode").toString();
        int count = (int) actionContext.getActionContext("count");
        //扣减冻结库存
        int updateCount = storageTCCMapper.unfreezeStorage(commodityCode, count);
        return updateCount > 0;
    }

    private void checkStock(String commodityCode, int count){
        log.info("检查 {} 的库存", commodityCode);
        Storage storage = storageTCCMapper.findByCommodityCode(commodityCode);
        if (Objects.isNull(storage) || storage.getCount() < count) {
            log.warn("{} 库存不足，当前剩余库存:{},需要扣减：{}", commodityCode, Objects.isNull(storage)?"空":storage.getCount(),count);
            throw new RuntimeException("当前库存不足");
        }
    }
}
